#ifndef ELF_H
#define ELF_H

// ELF相关数据类型
typedef uint32_t Elf32_Addr;
typedef uint16_t Elf32_Half;
typedef uint32_t Elf32_Off;
typedef uint32_t Elf32_Sword;
typedef uint32_t Elf32_Word;

#define EI_NIDENT 16

#define PT_NULL 0
#define PT_LOAD 1
#define PT_DYNAMIC 2
#define PT_INTERP 3
#define PT_NOTE 4
#define PT_SHLIB 5
#define PT_PHDR 6
#define PT_LOPROC 0x70000000
#define PT_HIPROC 0x7fffffff

#pragma pack(1)

typedef struct {
    char e_ident[EI_NIDENT];    //以0x7f,'E','L','F'开头
    Elf32_Half e_type;          
    Elf32_Half e_machine;
    Elf32_Word e_version;
    Elf32_Addr e_entry;         //系统首次转移控制的虚拟地址，如果文件没有关联的入口点，该成员为零
    Elf32_Off e_phoff;          //程序头表在文件中的偏移量（以字节为单位），如果文件没有程序头表为零
    Elf32_Off e_shoff;          //节头表在文件中的偏移量（以字节为单位）。如果文件没有节头表，这个成员的值为零。
    Elf32_Word e_flags;
    Elf32_Half e_ehsize;        //ELF文件头部的大小（以字节为单位）。
    Elf32_Half e_phentsize;     //文件的程序头表中单个条目的大小（以字节为单位）；所有的条目具有相同的大小。
    Elf32_Half e_phnum;         //程序头表中的条目数量
    Elf32_Half e_shentsize;     //文件的程序头表中单个条目的大小（以字节为单位），所有条目的大小相同
    Elf32_Half e_shnum;         //节头表中的条目数量
    Elf32_Half e_shstrndx;      
} Elf32_Ehdr;

typedef struct {
    Elf32_Word p_type;
    Elf32_Off p_offset;         // 从文件开始处到段首字节的偏移量。
    Elf32_Addr p_vaddr;         //在内存中段首字节所在的虚拟地址
    Elf32_Addr p_paddr;         // 段的物理地址
    Elf32_Word p_filesz;        //段在文件映像中的字节数,可能是零。
    Elf32_Word p_memsz;         //段在内存映像中的字节数,可能是零。
    Elf32_Word p_flags;         
    Elf32_Word p_align;
} Elf32_Phdr;

#pragma pack()

#endif  // ELF_H